package pe.com.cotelasa.seguridad.controlador;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;
import org.apache.log4j.Logger;
import org.primefaces.component.menubar.Menubar;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.Authentication;

import pe.com.cotelasa.common.controlador.MBGenerico;
import pe.com.cotelasa.scp.dominio.common.URLPaginacion;
import pe.com.cotelasa.scp.dominio.common.helper.SelectOneMenuHelper;
import pe.com.cotelasa.scp.dominio.excepcion.ServiceException;
import pe.com.cotelasa.scp.dominio.service.IServicioEmpresa;
import pe.com.cotelasa.scp.dominio.service.IServicioSede;
import pe.com.cotelasa.scp.entidad.Empresa;
import pe.com.cotelasa.scp.entidad.Sede;
import pe.com.cotelasa.seguridad.controlador.backingBean.BKSession;
import pe.com.cotelasa.seguridad.controlador.helper.MenuBarHelper;
import pe.com.cotelasa.seguridad.dominio.servicio.IServiceMenuRol;
import pe.com.cotelasa.seguridad.dominio.servicio.IServiceUsuario;
import pe.com.cotelasa.seguridad.entidad.Usuario;
import pe.com.cotelasa.seguridad.entidad.UsuarioEmpresa;

@Named(value = "MBAcceso")
@Scope("prototype")
public class MBAcceso extends MBGenerico implements Serializable {

    private static final long serialVersionUID = 9015531053058454499L;
    private static Logger logger = Logger.getLogger(MBAcceso.class);
    @Inject
    private BKSession bkSession;
    private boolean mostrarEmpresa = false;
    @Inject
    private AuthenticationManager authenticationManager;
    @Inject
    private IServiceMenuRol serviceMenuRol;
    @Inject
    private IServiceUsuario servicioUsuario;
    @Inject
    private IServicioEmpresa servicioEmpresa;
    @Inject
    private IServicioSede servicioSede;
    private Menubar principalMenuBar;

    public MBAcceso() {
    }

    public String validarAcceso() {
        Authentication request = new UsernamePasswordAuthenticationToken(this.bkSession.getUsuario().getUsuario().toUpperCase(), this.bkSession.getUsuario().getContracena());
        Authentication resultado = authenticationManager.authenticate(request);
        if (resultado.isAuthenticated()) {
            Usuario usuario = (Usuario) resultado.getPrincipal();
            this.bkSession.setUsuario(usuario);
            SecurityContextHolder.getContext().setAuthentication(resultado);

            boolean flag = false;
            try {
                flag = cargaInformacionSesion();
            } catch (Exception e) {
                mostrarError("Error al cargar Informacion de sesion");
            }
            if (flag) {
                return URLPaginacion.Seguridad.URL_HOME;
            } else {
                return URLPaginacion.Seguridad.URL_PASARELA;
            }
        } else {
            this.bkSession.setUsuario(new Usuario());
            SecurityContextHolder.getContext().setAuthentication(null);
            return URLPaginacion.Seguridad.URL_LOGIN;
        }
    }

    private boolean cargaInformacionSesion() throws Exception {
        List<Empresa> listaEmpresaPorUsuario = new ArrayList<Empresa>();
        this.bkSession.setVisible(true);
        try {
            Usuario beanUsuario = servicioUsuario.obtenerUsuarioPorId(this.bkSession.getUsuario().getId());
            Collection<UsuarioEmpresa> listaUsuarioEmpresa = beanUsuario.getUsuarioEmpresaCollection();
            for (UsuarioEmpresa usuarioEmpresa : listaUsuarioEmpresa) {
                listaEmpresaPorUsuario.add(usuarioEmpresa.getEmpresa());
            }

            if (listaEmpresaPorUsuario.size() == 0) {
                this.bkSession.setListaEmpresa(SelectOneMenuHelper.listaEmpresas(null));
                this.bkSession.setListaSede(SelectOneMenuHelper.listaSedes(null));
                mostrarError("Usted no tiene ninguna empresa asignada");
                logger.error("Usted no tiene ninguna empresa asignada");
                this.bkSession.setVisible(false);
            } else if (listaEmpresaPorUsuario.size() == 1) {
                this.bkSession.setListaEmpresa(SelectOneMenuHelper.listaEmpresas(listaEmpresaPorUsuario));
                bkSession.setEmpresa(servicioEmpresa.conseguirEmpresaConUbigeo(listaEmpresaPorUsuario.get(0).getId()));
                List<Sede> listaSede = new ArrayList<Sede>(listaEmpresaPorUsuario.get(0).getSedeCollection());
                if (listaSede.size() == 0) {
                    this.bkSession.setListaSede(SelectOneMenuHelper.listaSedes(null));
                    mostrarError("Usted no tiene ninguna sede asignada");
                    logger.error("Usted no tiene ninguna sede asignada");
                    this.bkSession.setVisible(false);
                } else if (listaSede.size() == 1) {
                    bkSession.setSede(servicioSede.conseguirSedePorId(listaSede.get(0).getId()));
                    return true;
                } else {
                    this.bkSession.setListaSede(SelectOneMenuHelper.listaSedes((List<Sede>) bkSession.getEmpresa().getSedeCollection()));
                }
            } else {
                this.bkSession.setListaEmpresa(SelectOneMenuHelper.listaEmpresas(listaEmpresaPorUsuario));
                this.bkSession.setListaSede(SelectOneMenuHelper.listaSedes(null));
            }
            return false;
        } catch (Exception e) {
            logger.error("Error al cargar Informacion de sesion", e);
            throw e;
        }
    }

    public void seleccionarSede() {
        logger.info("Seleccionado sede");
        try {
            Empresa empresa = servicioEmpresa.conseguirEmpresaConUbigeo(this.bkSession.getEmpresa().getId());
            this.bkSession.setEmpresa(empresa);
            if (this.bkSession.getEmpresa().getId() == -1 || this.bkSession.getEmpresa().getId() == -2) {
                this.bkSession.setListaSede(SelectOneMenuHelper.listaSedes(null));
            } else {
                this.bkSession.setListaSede(SelectOneMenuHelper.listaSedes((List<Sede>) empresa.getSedeCollection()));
            }
        } catch (ServiceException e) {
            logger.info(e.getMessage(), e);
            this.bkSession.setSede(new Sede());
            mostrarError(serviceProperties.getProperty("cotelasa.message.logueo.error"));
        }
    }

    public String entrar() {
        try {
            if (this.bkSession.getEmpresa().getId() != -1 && this.bkSession.getSede().getId() != -1) {
                this.bkSession.setSede(servicioSede.conseguirSedePorId(this.bkSession.getSede().getId()));
                return URLPaginacion.Seguridad.URL_HOME;
            } else {
                this.bkSession.setSede(new Sede());
                if (this.bkSession.getEmpresa().getId() == -1) {
                    mostrarError(serviceProperties.getProperty("cotelasa.message.logueo.error.empresa"));
                } else {
                    mostrarError(serviceProperties.getProperty("cotelasa.message.logueo.error.sede"));
                }
                return "";
            }
        } catch (ServiceException e) {
            logger.info(e.getMessage(), e);
            this.bkSession.setSede(new Sede());
            mostrarError(serviceProperties.getProperty("cotelasa.message.logueo.error"));
            return "";
        }
    }

    public String cerrar() {
        this.bkSession.setListaEmpresa(SelectOneMenuHelper.listaEmpresas(null));
        this.bkSession.setListaSede(SelectOneMenuHelper.listaSedes(null));
        this.bkSession.setUsuario(new Usuario());
        this.bkSession.setVisible(false);
        SecurityContextHolder.getContext().setAuthentication(null);
        return URLPaginacion.Seguridad.URL_LOGIN;
    }

    private void cargarMenuBar() {
        try {
            if (bkSession.getListaMenu() == null) {
                bkSession.setListaMenu(serviceMenuRol.obtenerListaMenuPorRol(this.bkSession.getUsuario().getIdRol().getId()));
            }
            this.setPrincipalMenuBar(MenuBarHelper.getMenuBar(bkSession.getListaMenu()));
        } catch (Exception e) {
            String msg = "no se pudo crear el componente menubar";
            mostrarError(msg);
            logger.error(e.getMessage(), e);
        }
    }

    public Menubar getPrincipalMenuBar() {
        cargarMenuBar();
        return principalMenuBar;
    }

    public void setPrincipalMenuBar(Menubar principalMenuBar) {
        this.principalMenuBar = principalMenuBar;
    }

    public boolean isMostrarEmpresa() {
        return mostrarEmpresa;
    }

    public void setMostrarEmpresa(boolean mostrarEmpresa) {
        this.mostrarEmpresa = mostrarEmpresa;
    }
}
